//
//  NetworkClient.m
//  CarService
//
//  Created by Nimo.Yu on 15/1/30.
//  Copyright (c) 2015年 lexingsoft. All rights reserved.
//

#import "NetworkClient.h"

#import <AFNetworkActivityIndicatorManager.h>
#import "DataManager.h"
#import "NetworkConfig.h"

#define TIMEOUT 60
static NSString *MethodGet = @"GET";
static NSString *MethodPost = @"POST";
static NSString *MethodPut =@"PUT";
static NSString *MethodDelete =@"DELETE";

static NSString *ResponseKeyRtnCode = @"status";
static NSString *ResponseKeyBizData = @"results";
static NSString *ResponseKeyMsg = @"message";

static NSString *serviceName=@"api";
static NSString *serviceVersion = @"1";

static NSString *AppIDKey=@"appKey";
static NSString *AppNameHttpKey=@"lexing-appname"; //@"public-app"
static NSString *AppversionHttpKey = @"lexing-appversion"; //@"1.0"
static NSString *PlatformHttpKey = @"lexing-appplatform"; //@“iOS”
static NSString *DeviceHttpKey = @"lexing-appdevice";     //@"iOS|8.1.3|iPhone 6"
static NSString *TokenHttpKey=@"token";
static NSString *AppProductKey=@"product";

static NSString *AppIDValue=@"LexingInternalApp";
static NSString *AppNameValue=@"public-app";
static NSString *PlatformValue=@"iOS";
static NSString *AppProductValue=@"Umibus_iOS";

@implementation NetworkClient

+ (instancetype )sharedInstance
{
    static NetworkClient *sharedInstance = nil;
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{
        sharedInstance = [[super alloc] init];
    });
    return sharedInstance;
}

+ (AFHTTPRequestOperationManager *) getManager
{
    static AFHTTPRequestOperationManager *manager = nil;
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{
        manager = [[AFHTTPRequestOperationManager alloc] init];
        AFJSONRequestSerializer *serializer = [AFJSONRequestSerializer serializer];
        [manager setRequestSerializer:serializer];
        AFJSONResponseSerializer *responseSerializer = [AFJSONResponseSerializer serializer];
        [manager setResponseSerializer:responseSerializer];
        manager.responseSerializer.acceptableContentTypes = [manager.responseSerializer.acceptableContentTypes setByAddingObject:@"text/html"];
        
        [[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES];
        
        NSOperationQueue *operationQueue = manager.operationQueue;
        [manager.reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
            DLog(@"Made it here.");
            
            switch (status) {
                case AFNetworkReachabilityStatusReachableViaWWAN:
                case AFNetworkReachabilityStatusReachableViaWiFi:
                    [operationQueue setSuspended:NO];
                    DLog(@"Reachable");
                    break;
                case AFNetworkReachabilityStatusNotReachable:
                default:
                    [operationQueue setSuspended:YES];
                    DLog(@"Not Reachable");
                    break;
            }
        }];
    });
    return manager;
}

//处理Token失效等问题
+ (void) checkToken:(AFHTTPRequestOperation *)operation Error:(NSError *)error
{
    dispatch_async(dispatch_get_main_queue(), ^{
        NSDictionary *dict = (NSDictionary *) operation.responseObject;
        NSString *strMessage=dict[ResponseKeyMsg];
        if(operation.response.statusCode==401){
            NSString *splitor=@"--";
            NSArray *array=[strMessage componentsSeparatedByString:splitor];
            if ([array.firstObject isEqualToString:@"USERID_OR_PASSWORD_NOT_VALID"]) {
                [[NSNotificationCenter defaultCenter] postNotificationName:LoginDidFailureNotification object:nil];
            }else if([array.firstObject isEqualToString:@"TOKEN_NOT_FOUND"])
            {
                [[NSNotificationCenter defaultCenter] postNotificationName:tokenFailureNotification object:nil];
            }
            return;
        }
    });
}

// 错误提示
+ (void) errorPrompt:(AFHTTPRequestOperation *)operation Error:(NSError *)error
{
    dispatch_async(dispatch_get_main_queue(), ^{
        DLog(@"Error: %ld", (long)operation.response.statusCode);
        DLog(@"Back Data:%@", operation.responseObject);
        NSDictionary *dict = (NSDictionary *) operation.responseObject;
        NSString *strMessage=dict[ResponseKeyMsg];
        if (operation.response.statusCode == 404) {
            [PromptAction showErrorPrompt:NSLocalizedString(@"Prompt_404", nil)];
            return;
        }
        if ([strMessage isEqualToString:@"EXCEEDING_MAX_ORDER"]) {
            [PromptAction showErrorPrompt:@"亲，请先完成您正在进行的订单哦~"];
            return;
        }
        if ([strMessage isEqualToString:@"AGENCY_CLOSED"]) {
            [PromptAction showErrorPrompt:@"商家已停止营业"];
            return;
        }
        if(operation.response.statusCode==401){
            return;
        }
        if (strMessage) {
            [PromptAction showErrorPrompt:NSLocalizedString(strMessage, nil)];
        }
        else if(error.code == -1001)
        {
            [PromptAction showErrorPrompt:NSLocalizedString(@"Prompt_RequestTimeout", nil)];
        }
        else{
            [PromptAction showErrorPrompt:NSLocalizedString(@"Pormpt_CantConnectServer", nil)];
        }
    });
}

#pragma mark - Upload File

+ (void) postUploadRequest:(NSString *) path
                parameters:(NSDictionary *)parameters
                NeedPrompt:(BOOL) needPrompt
 constructingBodyWithBlock:(void (^)(id <AFMultipartFormData> formData))block
             progressBlock:(void (^)(long long  sentBytes, long long  needSendBytes)) uploadProgressBlock
                   success:(void (^)(id dataObject))success
                   failure:(void (^)(id dataObject))failure
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        AFHTTPRequestOperationManager *manager = [NetworkClient getManager];
        NSString *domainAddress = [NetworkClient getAddressWithSerivce];
        if (domainAddress != nil) {
            NSString *requestString = [NSString stringWithFormat:@"%@%@", domainAddress,path];
            NSMutableURLRequest *request = [manager.requestSerializer multipartFormRequestWithMethod:MethodPost URLString:requestString parameters:parameters constructingBodyWithBlock:block error:nil];
            [NetworkClient sendUploadRequest:request NeedPrompt:needPrompt progressBlock:uploadProgressBlock success:success failure:failure];
        }else {
            [NetworkClient errorPrompt:nil Error:nil];
        }
    });
}

+ (void) sendUploadRequest:(NSMutableURLRequest *) request
            NeedPrompt:(BOOL) needPrompt
         progressBlock:(void (^)(long long sentBytes, long long needSendBytes)) uploadProgressBlock
               success:(void (^)(id dataObject))success
               failure:(void (^)(id resultDict))failure
{
    AFHTTPRequestOperationManager *manager = [NetworkClient getManager];
    
    [request setTimeoutInterval:60];
    
    [request setValue:[NetworkClient getAppVersion] forHTTPHeaderField:AppversionHttpKey];
    [request setValue:[NetworkClient getDeviceInfo] forHTTPHeaderField:DeviceHttpKey];
    [request setValue:AppNameValue forHTTPHeaderField:AppNameHttpKey];
    [request setValue:PlatformValue forHTTPHeaderField:PlatformHttpKey];
    [request setValue:AppIDValue forHTTPHeaderField:AppIDKey];
    [request setValue:AppProductValue forHTTPHeaderField:AppProductKey];
    
    NSString *token=[DataManager sharedInstance].userToken;
    if (token) {
        [request setValue:token forHTTPHeaderField:TokenHttpKey];
    }
    DLog(@"%@", request);
    DLog(@"%@", request);
    // send request
    [[AFNetworkActivityIndicatorManager sharedManager] incrementActivityCount];
    
    AFHTTPRequestOperation *operation = [manager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
        [[AFNetworkActivityIndicatorManager sharedManager] decrementActivityCount];
        // 主线程
        dispatch_async(dispatch_get_main_queue(), ^{
            DLog(@"responseObject = %@", responseObject);
            NSDictionary *resultDict = responseObject;
            NSNumber *stautsCode = resultDict[ResponseKeyRtnCode];
            NSString *_strMessage = resultDict[ResponseKeyMsg];
            
            id dataObject = resultDict[ResponseKeyBizData];
            if ([stautsCode intValue] == 200) {
                success(dataObject);
            }else {
                // 业务驱动的提示
                BOOL blockNeedPrompt = needPrompt;
                DLog(@"error mess -- %@",_strMessage);
                if (blockNeedPrompt) {
                    [NetworkClient errorPrompt:operation Error:nil];
                }
                failure(resultDict);
            }
        });
        
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        [[AFNetworkActivityIndicatorManager sharedManager] decrementActivityCount];
        // 主线程
        dispatch_async(dispatch_get_main_queue(), ^{
            
            if (needPrompt) {
                [NetworkClient errorPrompt:operation Error:error];
            }
            failure(operation.responseObject);
        });
    }];
    
    [operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
        uploadProgressBlock(totalBytesWritten, totalBytesExpectedToWrite);
    }];
    
    [manager.operationQueue addOperation:operation];
}

+ (NSOperation *)downloadRequest:(NSString *) path
              parameters:(NSDictionary *)parameters
               savedPath:(NSString*)savedPath
         downloadSuccess:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
         downloadFailure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
                progress:(void (^)(float progress, NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead))progress
{
    AFHTTPRequestSerializer *serializer = [AFHTTPRequestSerializer serializer];
    NSMutableURLRequest *request =[serializer requestWithMethod:@"POST" URLString:path parameters:parameters error:nil];
    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc]initWithRequest:request];
    [operation setOutputStream:[NSOutputStream outputStreamToFileAtPath:savedPath append:NO]];
    [operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
        float p = (float)totalBytesRead / totalBytesExpectedToRead;
        progress(p,bytesRead,totalBytesRead,totalBytesExpectedToRead);
        NSLog(@"download：%f", (float)totalBytesRead / totalBytesExpectedToRead);
    }];
    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        success(operation,responseObject);
        NSLog(@"下载成功");
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        failure(operation,error);
        NSLog(@"下载失败");
    }];
    [operation start];
    return operation;
}

+ (void) sendRequest:(NSMutableURLRequest *) request
          NeedPrompt:(BOOL) needPrompt
             success:(void (^)(id dataObject))success
             failure:(void (^)(id resultDict))failure
{
    
    AFHTTPRequestOperationManager *manager = [NetworkClient getManager];
    //设置缓存策略为不加载缓存
    [request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
    [request setTimeoutInterval:TIMEOUT];
    [request setValue:[NetworkClient getAppVersion] forHTTPHeaderField:AppversionHttpKey];
    [request setValue:[NetworkClient getDeviceInfo] forHTTPHeaderField:DeviceHttpKey];
    [request setValue:AppNameValue forHTTPHeaderField:AppNameHttpKey];
    [request setValue:PlatformValue forHTTPHeaderField:PlatformHttpKey];
    [request setValue:AppIDValue forHTTPHeaderField:AppIDKey];
    [request setValue:AppProductValue forHTTPHeaderField:AppProductKey];
    [request setValue:@"application/json" forHTTPHeaderField:@"content-Type"];
    
    NSString *token=[DataManager sharedInstance].userToken;
    if (token) {
        [request setValue:token forHTTPHeaderField:TokenHttpKey];
    }
    DLog(@"Request:%@", request);
    // send request
    [[AFNetworkActivityIndicatorManager sharedManager] incrementActivityCount];
    
    AFHTTPRequestOperation *operation = [manager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
        [[AFNetworkActivityIndicatorManager sharedManager] decrementActivityCount];
        // 主线程
        dispatch_async(dispatch_get_main_queue(), ^{
            
            if ([responseObject yn_description]) {
                DLog(@"\n\nRequest:%@ \n\nallHTTPHeaderFields:%@ \n\nHTTPBody:%@ \n\nresponseObject = %@", request,request.allHTTPHeaderFields,[[NSString alloc] initWithData:request.HTTPBody encoding:NSUTF8StringEncoding],[responseObject yn_description]);
            }else
            {
                DLog(@"\n\nRequest:%@ \n\nallHTTPHeaderFields:%@ \n\nHTTPBody:%@ \n\nresponseObject = %@", request,request.allHTTPHeaderFields,[[NSString alloc] initWithData:request.HTTPBody encoding:NSUTF8StringEncoding],responseObject);
            }
            success(responseObject[@"results"]);
//            NSDictionary *resultDict = responseObject;
//            id dataObject = resultDict[ResponseKeyBizData];
//            if (dataObject==nil)
//            {
//                success(resultDict[@"data"]);
//            }else
//            {
//                success(dataObject);
//            }
//            NSNumber *stautsCode = resultDict[ResponseKeyRtnCode];
//            NSString *strMessage = resultDict[ResponseKeyMsg];
//            
//            id dataObject = resultDict[ResponseKeyBizData];
//            if ([stautsCode intValue]==200) {
//                success(dataObject);
////                [PromptAction dismissPrompt];
//            }else{
////                // 业务驱动的提示
//                BOOL blockNeedPrompt = needPrompt;
////                if ([stautsCode isEqualToString:NoNeedPormptCode_UnRegister]) {
////                    blockNeedPrompt = NO;
////                }
////                
//                DLog(@"error mess -- %@",strMessage);
//                [NetworkClient checkToken:operation Error:nil];
//                if (blockNeedPrompt) {
//                    [NetworkClient errorPrompt:operation Error:nil];
//                }else {
//                    [PromptAction dismissPrompt];
//                }
//                failure(resultDict);
//            }
        });
        
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSString *stringValue=[[NSString alloc] initWithData:operation.responseData encoding:NSUTF8StringEncoding];
        if ([operation.response yn_description]) {
            DLog(@"\n\nRequest:%@ \n\nallHTTPHeaderFields:%@ \n\nHTTPBody:%@ \n\nresponseObject = %@ \n responseData:%@", request,request.allHTTPHeaderFields,[[NSString alloc] initWithData:request.HTTPBody encoding:NSUTF8StringEncoding],[operation.response yn_description],stringValue);
        }else
        {
            DLog(@"\n\nRequest:%@ \n\nallHTTPHeaderFields:%@ \n\nHTTPBody:%@ \n\nresponseObject = %@ \n responseData:%@", request,request.allHTTPHeaderFields,[[NSString alloc] initWithData:request.HTTPBody encoding:NSUTF8StringEncoding],operation.response,stringValue);
        }
        DLog(@"%@",error);
        if (error) {
            NSData *data=error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey];
            if (data) {
                id object=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
                DLog(@"%@: %@",AFNetworkingOperationFailingURLResponseDataErrorKey,object);
                NSString *devmsg=object[@"developerMessage"];
                DLog(@"%@",devmsg);
            }
        }
        [[AFNetworkActivityIndicatorManager sharedManager] decrementActivityCount];
        // 主线程
        dispatch_async(dispatch_get_main_queue(), ^{
            [NetworkClient checkToken:operation Error:error];
            if (needPrompt) {
                [NetworkClient errorPrompt:operation Error:error];
            }else {
//                [PromptAction dismissPrompt];
            }
            failure(operation.responseObject);
        });
    }];
    
    [manager.operationQueue addOperation:operation];
}

+ (void) postRequest:(NSString *) path
          parameters:(NSDictionary *)parameters
    headerParameters:(NSDictionary *)headerParameters
          needPrompt:(BOOL) needPrompt
             success:(void (^)(id dataObject))success
             failure:(void (^)(id resultDict))failure
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        AFHTTPRequestOperationManager *manager = [NetworkClient getManager];
        NSString *domainAddress = [NetworkClient getAddressWithSerivce];
        if (domainAddress != nil) {
            NSString *requestString = [NSString stringWithFormat:@"%@%@", domainAddress,path];
            DLog(@"%@",parameters);
            
            NSMutableURLRequest *request = [manager.requestSerializer requestWithMethod:MethodPost URLString:requestString parameters:parameters error:nil];
            for (NSString *key in headerParameters.allKeys) {
                [request setValue:headerParameters[key] forHTTPHeaderField:key];
            }
            [NetworkClient sendRequest:request NeedPrompt:needPrompt success:success failure:failure];
        }else{
        }
    });
}

+ (void) postRequest:(NSString *) path
          parameters:(NSDictionary *)parameters
          NeedPrompt:(BOOL) needPrompt
             success:(void (^)(id dataObject))success
             failure:(void (^)(id resultDict))failure
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        AFHTTPRequestOperationManager *manager = [NetworkClient getManager];
        NSString *domainAddress = [NetworkClient getAddressWithSerivce];
        if (domainAddress != nil) {
            NSString *requestString = [NSString stringWithFormat:@"%@%@", domainAddress,path];
            DLog(@"%@",parameters);
            
            NSMutableURLRequest *request = [manager.requestSerializer requestWithMethod:MethodPost URLString:requestString parameters:parameters error:nil];
            
            [NetworkClient sendRequest:request NeedPrompt:needPrompt success:success failure:failure];
            
        }else{
        }
    });
}

+ (void) getRequest:(NSString *) path
         parameters:(NSDictionary *)parameters
         NeedPrompt:(BOOL) needPrompt
            success:(void (^)(id dataObject))success
            failure:(void (^)(id dataObject))failure
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        AFHTTPRequestOperationManager *manager = [NetworkClient getManager];
        NSString *domainAddress = [NetworkClient getAddressWithSerivce];
        if (domainAddress != nil) {
            NSString *requestString = [NSString stringWithFormat:@"%@%@", domainAddress,path];
            NSMutableURLRequest *request = [manager.requestSerializer requestWithMethod:MethodGet URLString:requestString parameters:parameters error:nil];
            [NetworkClient sendRequest:request NeedPrompt:needPrompt success:success failure:failure];
        }else {
            [NetworkClient errorPrompt:nil Error:nil];
        }
    });
}

+ (void) putRequest:(NSString *) path
          parameters:(NSDictionary *)parameters
          NeedPrompt:(BOOL) needPrompt
             success:(void (^)(id dataObject))success
             failure:(void (^)(id resultDict))failure
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        AFHTTPRequestOperationManager *manager = [NetworkClient getManager];
        NSString *domainAddress = [NetworkClient getAddressWithSerivce];
        if (domainAddress != nil) {
            NSString *requestString = [NSString stringWithFormat:@"%@%@", domainAddress,path];
            DLog(@"%@",parameters);
            
            NSMutableURLRequest *request = [manager.requestSerializer requestWithMethod:MethodPut URLString:requestString parameters:parameters error:nil];
            
            [NetworkClient sendRequest:request NeedPrompt:needPrompt success:success failure:failure];
            
        }else{
        }
    });
}

+ (void) putRequest:(NSString *) path
         parameters:(NSDictionary *)parameters
   headerParameters:(NSDictionary *)headerParameters
         NeedPrompt:(BOOL) needPrompt
            success:(void (^)(id dataObject))success
            failure:(void (^)(id resultDict))failure
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        AFHTTPRequestOperationManager *manager = [NetworkClient getManager];
        NSString *domainAddress = [NetworkClient getAddressWithSerivce];
        if (domainAddress != nil) {
            NSString *requestString = [NSString stringWithFormat:@"%@%@", domainAddress,path];
            DLog(@"%@",parameters);
            
            NSMutableURLRequest *request = [manager.requestSerializer requestWithMethod:MethodPut URLString:requestString parameters:parameters error:nil];
            for (NSString *key in headerParameters.allKeys) {
                [request setValue:headerParameters[key] forHTTPHeaderField:key];
            }
            [NetworkClient sendRequest:request NeedPrompt:needPrompt success:success failure:failure];
            
        }else{
        }
    });
}


+ (void) deleteRequest:(NSString *) path
         parameters:(NSDictionary *)parameters
         NeedPrompt:(BOOL) needPrompt
            success:(void (^)(id dataObject))success
            failure:(void (^)(id resultDict))failure
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        AFHTTPRequestOperationManager *manager = [NetworkClient getManager];
        NSString *domainAddress = [NetworkClient getAddressWithSerivce];
        if (domainAddress != nil) {
            NSString *requestString = [NSString stringWithFormat:@"%@%@", domainAddress,path];
            DLog(@"%@",parameters);
            
            NSMutableURLRequest *request = [manager.requestSerializer requestWithMethod:MethodDelete URLString:requestString parameters:parameters error:nil];
            
            [NetworkClient sendRequest:request NeedPrompt:needPrompt success:success failure:failure];
            
        }else{
        }
    });
}

- (NSDictionary *) getClientDict {
    
    if (YES) {
        NSString *appVersion = @"客户端版本号";
        NSString *clientModel = @"机型";
        NSString *carrierName = @"访问网络类型";
        UIDevice *currentDevice = [UIDevice currentDevice];
        NSString *clientOs = currentDevice.systemVersion;
        
        NSMutableDictionary *clientInfoDict = [NSMutableDictionary dictionary];
        [clientInfoDict setValue:appVersion forKey:@"version"]; // 客户端版本号
        [clientInfoDict setValue:clientModel forKey:@"clientModel"]; // 客户端机型
        [clientInfoDict setValue:clientOs forKey:@"clientOs"]; // 客户端系统版本
        [clientInfoDict setValue:carrierName forKey:@"cNet"]; // 访问网络类型
    }
    
    return nil;
}

+ (NSString *)getHostAddress{
    NSString *host=lookUpAddress;
    if ([DataManager sharedInstance].testHost) {
        host=[DataManager sharedInstance].testHost;
    }else if ([DataManager sharedInstance].qaHost) {
        host=[DataManager sharedInstance].qaHost;
    }
    return host;
}

// 获取不同业务的域名
+ (NSString *) getAddressWithSerivce
{
    NSString *host=[self getHostAddress];
    return [NSString stringWithFormat:@"%@/%@",host,serviceName];
//    return [NSString stringWithFormat:@"%@/%@/%@",host,serviceName,serviceVersion];
}

+ (NSString *)getDeviceInfo
{
    UIDevice *device=[UIDevice currentDevice];
    NSString *deviceInfo=[NSString stringWithFormat:@"%@|%@|%@",device.systemName,device.systemVersion,device.model];
    return deviceInfo;
}

+ (NSString *)getAppVersion
{
    NSString *version=[TakeInfoPlist CFBundle_ShortVersionString];
    return version;
}
@end
